package gates;

import master.*;
import java.math.*;


/**
 * 
 * @author Rupert
 * 
 * Quantum Fourier transformation. Implemented as a succession of Hadamard and Phaseshift gates.
 * Reminder: this is not a composed gate, this just applies Hadamard and Phaseshift gates to the 
 * register in the right succession.
 *
 */

public class QuantumFourier extends QuantumGate {

	
	/**
	 * The actual routine combines the hadamard on a certain bit
	 * and all following controlled phaseshifts in one loop. I.e:
	 * Hadamard(0) + phaseshift
	 * Hadamard(1) + phaseshift + phaseshift 
	 * ...
	 * Hadamard(n-1)
	 * 
	 * The System Outputs in the comments can be used to display
	 * what gates are apllied.
	 *
	 *
	 */
	
	public static void applyFourier(QuantumRegister reg) {
		
		QuantumGate gate;
		int N = reg.getQBitLength();
		
		for (int n = 0; n < N-1; n++) {
			
			gate = new Hadamard(n);
			gate.actOnReg(reg);
//			System.out.println("Hadamard: "+ n);
			for (int m = 0; m <= n; m++) {
				gate = new ControlledPhaseShift(n + 1, m, (float) (Math.PI
						/ (Math.pow(2, (n+1-m)))));
				gate.actOnReg(reg);
//				System.out.println("Phaseshift, cbit:" + (n+1) + " abit: " +m + "Phase:Pi/ " + (Math.pow(2, (n+1-m))));
			}
		}
		
		gate = new Hadamard(N-1);
		gate.actOnReg(reg);
//		System.out.println("Hadamard: "+ (N-1));
		
	}
	
	public int[] getActingBits() {
		int[] a = new int[1];
		a[0] = -1;
		return a;   
	}

}
